﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq.Dynamic;
using System.Web.Mvc;
using SDT.Model;
using SDT.Lib.Common;
using SDT.Site.Properties;
using SDT.Site.ViewModels;
using SDT.Lib.Paging;
using System.Web.UI.WebControls;
using System.IO;
using System.Data.Linq;
using SDT.Lib.Helpers;
using System.Web.Security;
using System.Configuration;
using SDT.Lib.Mail;

namespace SDT.Site.Controllers
{
    public class DealController : Controller
    {
        //
        // GET: /Deal/

        SDTDataContext db = new SDTDataContext();
        public ActionResult Index(int? id, int? priceid, int? typeid, int? holidayid, int? page)
        {
            if (page == null) page = 1; ;
            var pageIndex = page.Value - 1;
            var pageSize = Convert.ToInt32(UserState.getUserStateFromRequest("deal.PageSize", "pageSize", Settings.Default.ProductPageSize));
            string order = UserState.getUserStateFromRequest("deal.order", "order", "AddDate").ToString();
            string orderDir = UserState.getUserStateFromRequest("deal.orderDir", "orderDir", "desc").ToString();
            ViewData["orderDir"] = orderDir;
            ViewData["order"] = order;
            DealIndexModels p = new DealIndexModels();
            p.CategoryID = id.HasValue ? id.Value : 0;
            p.HolidayID = holidayid.HasValue ? holidayid.Value : 0;
            p.PriceID = priceid.HasValue ? priceid.Value : 0;
            p.TypeID = typeid.HasValue ? typeid.Value : 0;
            p.Keyword = Request["key"] != null ? Request["key"] : string.Empty;
            //sellid = 1 newyn=true, 2: hotyn, 3: saleyn, 4: promoyn
            p.Products = ProductManager.GetList(p.TypeID, p.CategoryID, p.HolidayID, p.PriceID, 0,
                0, p.Keyword, 0, 1, 0, 0, 0, 1, order, orderDir, pageIndex, pageSize);
            p.ImageUrl = Settings.Default.SiteRootUrl + Settings.Default.ProductRootUrl;
            p.ImagePath = Settings.Default.SiteRootPath + Settings.Default.ProductRootPath;


            p.Categories = db.ProductCategories.Where(e => e.ActiveYN == true && e.ID != p.CategoryID).OrderBy(e => e.Priority).ToList();
            p.ConvertPrices = db.ConvertPrices.ToList();
            p.ProductTypes = db.ProductTypes.ToList();
            p.ProductHolidays = db.ProductHolidays.OrderBy(e => e.Priority).ToList();
            p.ProductType = db.ProductTypes.Where(e => e.ID == p.TypeID).SingleOrDefault();
            p.Category = db.ProductCategories.Where(e => e.ID == p.CategoryID).SingleOrDefault();
            p.ConvertPrice = db.ConvertPrices.Where(e => e.ID == p.PriceID).SingleOrDefault();
            p.ProductHoliday = db.ProductHolidays.Where(e => e.ID == p.HolidayID).SingleOrDefault();
            if (p.Category != null)
            {
                p.Categories.Insert(0, p.Category);
            }
            return View(p);
        }
        public ActionResult Details(int id)
        {
            DealDetailsModels p = new DealDetailsModels();
            p.Product = db.Products.Where(e => e.ID == id).SingleOrDefault();
            p.ImageUrl = Settings.Default.SiteRootUrl + Settings.Default.ProductRootUrl;
            p.ImagePath = Settings.Default.SiteRootPath + Settings.Default.ProductRootPath ;
            p.LogoPath = Settings.Default.SiteRootPath + Globals.DefaultLogoPath;


            p.DealIndexModel = new DealIndexModels();
            p.DealIndexModel.Categories = db.ProductCategories.Where(e => e.ActiveYN == true && e.ID != p.Product.CatID).OrderBy(e => e.Priority).ToList();
            p.DealIndexModel.Categories.Insert(0, p.Product.ProductCategory);
            p.DealIndexModel.ConvertPrices = db.ConvertPrices.ToList();
            p.DealIndexModel.ProductHolidays = db.ProductHolidays.OrderBy(e => e.Priority).ToList();
            p.DealIndexModel.ProductTypes = db.ProductTypes.ToList();

            p.DealIndexModel.Category = p.Product.ProductCategory;
            p.DealIndexModel.ConvertPrice = null;

            p.DealIndexModel.CategoryID = p.Product.CatID;
            p.DealIndexModel.PriceID = 0;
            p.DealIndexModel.PathTitle = p.Product.Name;

            p.Keyword = string.Empty;
            //luot xem
            var pr = db.Products.SingleOrDefault(d => d.ID == id);
            pr.nViews++;
            db.SubmitChanges();
            return View(p);
        }
        [ChildActionOnly]
        public ActionResult Gets(int typeid, int? catid, int? holidayid, int number,
            int hotYN, string order, string orderDir, string title, string viewName)
        {
            var p = new ProductListModels();
            var db = new SDTDataContext();
            var l = ProductManager.GetList(typeid, catid, holidayid, 0, 0, hotYN,1,0,0,0, 1, string.Empty, order, orderDir, number);
            p.Products = l;
            p.ImageUrl = Settings.Default.SiteRootUrl + Settings.Default.ProductRootUrl;
            p.ImagePath = Settings.Default.SiteRootPath + Settings.Default.ProductRootPath;
            ViewData["Title"] = title;
            return PartialView(viewName, p);
        }
        [ChildActionOnly]
        public ActionResult LatestComments(int id, int number)
        {
            var latestC = new List<Comment>();
            try
            {
                latestC = ProductManager.GetComments(id, true, number).ToList();
            }
            catch (Exception exp)
            {
                ErrorLog.WriteLog(exp);
            }
            return PartialView(latestC);
        }
        [ChildActionOnly]
        public ActionResult Comment(int id)
        {
            var c = new Comment();
            return PartialView(c);
        }
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Comment(int id, Comment c)
        {
            try
            {
                UpdateModel(c);
                if (c.Title != null && c.Title != string.Empty)
                {
                    c.CommentDate = DateTime.Now;
                    c.PublishYN = false;
                    db.Comments.InsertOnSubmit(c);
                    db.SubmitChanges();
                    var map = new CommentsInProduct();
                    map.CommentID = c.ID;
                    map.ProductID = id;
                    db.CommentsInProducts.InsertOnSubmit(map);
                    db.SubmitChanges();
                }
                return RedirectToAction("Details", new { id = id });
            }
            catch (Exception exp)
            {
                return RedirectToAction("Details", new { id = id });
            }
        }
        public ActionResult Create(int id)
        {
            Session[Messages.DealCart] = null;
            var cart = new DealCartViewModels();
            var productID = id;
            var number = 1;
            var p = db.Products.Where(e => e.ID == productID).SingleOrDefault();

            if (p != null)
            {
                cart.Product = p;
                cart.Quantity = number;
            }
            Session[Messages.DealCart] = cart;
            return RedirectToAction("cart");
        }
        [HttpPost]
        public ActionResult Create()
        {
            var cart = Session[Messages.DealCart] != null ? (DealCartViewModels)Session[Messages.DealCart] : new DealCartViewModels();
            var productID = Request["hdProductID"] != null && Request["hdProductID"] != string.Empty ?
                Utils.ParseInt(Request["hdProductID"]) : -1;
            var number = Request["txtQuantity"] != null && Request["txtQuantity"] != string.Empty && Utils.ParseInt(Request["txtQuantity"])>0 ?
                Utils.ParseInt(Request["txtQuantity"]) : 1;
            var p = db.Products.Where(e => e.ID == productID).SingleOrDefault();

            if (p != null)
            {
                cart.Product = p;
                cart.Quantity = number;
            }
            Session[Messages.DealCart] = cart;
            return RedirectToAction("cart");
        }
        public ActionResult Cart()
        {
            var cart = Session[Messages.DealCart] != null ? (DealCartViewModels)Session[Messages.DealCart] : new DealCartViewModels();
            cart.Cities = db.Cities.ToList();
            cart.Districts = db.Districts.ToList();
            cart.Sexuals = Utils.StringToDictionaryIntString(Settings.Default.CustomerSexual, ",");
            cart.Customer = User.Identity.Name != null ? CustomerManager.GetUser(User.Identity.Name) : null;
            cart.Payments = db.Payments.OrderBy(e => e.Priority).ToList();
            cart.Cities = db.Cities.ToList();
            cart.Districts = cart.Customer != null && cart.Customer.CityID > 0 ?
                db.Districts.Where(e => e.CityID == cart.Customer.CityID).ToList() : new List<District>();
            return View(cart);
        }
        [HttpPost]
        public ActionResult Updated()
        {
            var cart = Session[Messages.DealCart] != null ? (DealCartViewModels)Session[Messages.DealCart] : new DealCartViewModels();
            if (cart.Product!=null)
            {
                var number = Utils.ParseInt(Request["quantityList" + cart.Product.ID]);
                cart.Quantity = number;
            }
            Session[Messages.DealCart] = cart;
            return RedirectToAction("cart");
        }
        [HttpPost]
        public ActionResult Order(DealCartViewModels cart)
        {
            try
            {
                if (Request["CaptchaText"].ToLower() == HttpContext.Session["captchastring"].ToString().ToLower())
                {
                    cart = Session[Messages.DealCart] != null ? (DealCartViewModels)Session[Messages.DealCart] : new DealCartViewModels();
                    cart.Order = new Order();
                    UpdateModel(cart);
                    cart.Customer = db.Customers.Where(e => e.UserName == User.Identity.Name).SingleOrDefault();
                    var coupon = Utils.GetRandomPassword(6);
                    if (cart.Product!=null && cart.Customer != null)
                    {
                        
                        
                        cart.Order.Customer = cart.Customer;
                        cart.Order.AddDate = DateTime.Now;
                        cart.Order.City = db.Cities.Where(e => e.ID == Utils.ParseInt(Request["ddlCity"])).SingleOrDefault();
                        cart.Order.District = db.Districts.Where(e => e.ID == Utils.ParseInt(Request["ddlDistrict"])).SingleOrDefault();

                        var d = Request["txtReceiveDate"] != null ? Utils.ParseDateTime(Request["txtReceiveDate"].ToString(), new System.Globalization.CultureInfo("vi-VN")) : DateTime.Now;
                        var h = Request["txtReceiveHour"] != null ? Utils.ParseInt(Request["txtReceiveHour"]) : 0;
                        var m = Request["txtReceiveMinute"] != null ? Utils.ParseInt(Request["txtReceiveMinute"]) : 0;
                        d = d.AddHours(h);
                        d = d.AddMinutes(m);
                        cart.Order.Coupon = coupon;
                        cart.Order.OrderName = "Hóa đơn mua hàng deal của " + cart.Order.ReFullName;
                        cart.Order.ReceiveDate = d;
                        cart.Order.ReEmail = cart.Customer.Email;
                        cart.Order.Status = OrderStatus.New;
                        cart.Order.PaymentID = Utils.ParseInt(Request["rdoPayment"]);
                        cart.Order.SeAddress = cart.Customer.Address;
                        cart.Order.SeEmail = cart.Customer.Email;
                        cart.Order.SePhone = cart.Customer.MobilePhone;
                        cart.Order.SeFullName = cart.Customer.FullName;
                        cart.Order.TypeID = OrderType.Deal;
                        db.Orders.InsertOnSubmit(cart.Order);
                        db.SubmitChanges();
                        
                        var dt = new OrderDetail();
                        dt.Order = cart.Order;
                        dt.ProductID = cart.Product.ID;
                        dt.Price = cart.Product.UnitPrice.HasValue ? cart.Product.UnitPrice.Value : 0;
                        dt.Quantity = cart.Quantity;
                        dt.DiscountPercent = cart.Product.DiscountPercent;
                        dt.DiscountValue = cart.Product.DiscountValue;
                        db.OrderDetails.InsertOnSubmit(dt);
                        db.SubmitChanges();
                        decimal total = 0;
                        total = dt.Price * dt.Quantity;
                        var shipVal = cart.Product.FreeShipping.HasValue ? (decimal)cart.Product.FreeShipping.Value : 0;
                        cart.Order.ShippingValue = shipVal;
                        cart.Order.TotalValue = total + shipVal;
                        db.SubmitChanges();
                        //Send Mail
                        string activePasswordSubject = "[Muaqua.vn] Phiếu mua hàng giảm giá";
                        string fromMail = ConfigurationManager.AppSettings["DefaultFromMail"];
                        try
                        {
                            using (StreamReader sr = new StreamReader(Server.MapPath("~/Uploads/Mail/Deal.htm")))
                            {
                                string stringBody = sr.ReadToEnd();
                                var _messageBody = stringBody;
                                _messageBody = _messageBody.Replace("+ContactName+", cart.Customer.FullName != null && cart.Customer.FullName != string.Empty ?
                                    cart.Customer.FullName : cart.Customer.Email);
                                _messageBody = _messageBody.Replace("+Product+", cart.Product.Name);
                                _messageBody = _messageBody.Replace("+Coupon+", coupon);
                                SmtpMailer.sendMail(cart.Customer.Email, fromMail, activePasswordSubject, _messageBody);
                            }

                        }
                        catch (Exception exp)
                        {
                            ViewData[Messages.MessageInfo] = exp.Message;
                        }
                        Session[Messages.DealCart] = null;
                    }
                    if (Utils.ParseInt(Request["rdoPayment"]) == PaymentMethod.Nganluong)
                    {
                        var total = cart.Product.UnitPrice*cart.Quantity;

                        var url = NganluongPaymentManager.buildCheckoutUrl(Settings.Default.SiteRootUrl + "deal/validatenganluong",
                            ConfigurationManager.AppSettings["ReceiveFromMail"], "Hóa đơn mua hàng deal của " + (cart.Customer.FullName != null && cart.Customer.FullName != string.Empty ?
                            cart.Customer.FullName : cart.Customer.Email), cart.Order.ID.ToString(), total.ToString());
                        return Redirect(url);
                    }
                    else if (Utils.ParseInt(Request["rdoPayment"]) == PaymentMethod.OnePay)
                    {
                        var url = OnePayManager.BuildOnepayCheckoutUrl(Settings.Default.SiteRootUrl, cart.Order,true);
                        return Redirect(url);
                    }
                    else if (Utils.ParseInt(Request["rdoPayment"]) == PaymentMethod.OnePayWorld)
                    {
                        var url = OnePayManager.BuildOnepayCheckoutUrlWorld(Settings.Default.SiteRootUrl, cart.Order, true);
                        return Redirect(url);
                    }
                    return View("Success");
                }
                else
                {
                    ViewData[Messages.MessageInfo] = Messages.ERR_CAPTCHA_VALIDATE;
                    return View();
                }
            }
            catch (Exception exp)
            {
                ErrorLog.WriteLog(exp);
                return View("Fail");
            }
        }
        public ActionResult ValidateNganluong()
        {
            try
            {
                var error = Request["error_text"];
                if (error != null && error != string.Empty && error != "00")
                {
                    return View("Fail");
                }
                var paidYN = NganluongPaymentManager.verifyPaymentUrl(Request["transaction_info"], Request["order_code"],
                    Request["price"], Request["payment_id"], Request["payment_type"], Request["error_text"], Request["secure_code"]);
                if (paidYN == true)
                {
                    var orderID = Utils.ParseInt(Request["order_code"]);
                    if (orderID > 0)
                    {
                        var o = db.Orders.Where(e => e.ID == orderID).SingleOrDefault();
                        if (o != null)
                        {
                            o.Status = OrderStatus.Paid;
                            db.SubmitChanges();
                        }
                    }
                    else
                    {
                        return View("Fail");
                    }
                }
                return View("Success");
            }
            catch (Exception exp)
            {
                ErrorLog.WriteLog(exp);
                return View("Fail");
            }
        }
        public ActionResult ValidateOnePay()
        {
            try
            {
                string SECURE_SECRET = OnePayPayment.Hashcode;
                string hashvalidateResult = "";
                // Khoi tao lop thu vien
                VPCRequest conn = new VPCRequest("http://onepay.vn");
                conn.SetSecureSecret(SECURE_SECRET);
                // Xu ly tham so tra ve va kiem tra chuoi du lieu ma hoa
                hashvalidateResult = conn.Process3PartyResponse(Request.QueryString);

                // Lay gia tri tham so tra ve tu cong thanh toan
                String vpc_TxnResponseCode = conn.GetResultField("vpc_TxnResponseCode", "Unknown");
                string amount = conn.GetResultField("vpc_Amount", "Unknown");
                string localed = conn.GetResultField("vpc_Locale", "Unknown");
                string command = conn.GetResultField("vpc_Command", "Unknown");
                string version = conn.GetResultField("vpc_Version", "Unknown");
                string cardBin = conn.GetResultField("vpc_Card", "Unknown");
                string orderInfo = conn.GetResultField("vpc_OrderInfo", "Unknown");
                string merchantID = conn.GetResultField("vpc_Merchant", "Unknown");
                string authorizeID = conn.GetResultField("vpc_AuthorizeId", "Unknown");
                string merchTxnRef = conn.GetResultField("vpc_MerchTxnRef", "Unknown");
                string transactionNo = conn.GetResultField("vpc_TransactionNo", "Unknown");
                string txnResponseCode = vpc_TxnResponseCode;
                string message = conn.GetResultField("vpc_Message", "Unknown");

                // Sua lai ham check chuoi ma hoa du lieu
                var orderID = Utils.ParseInt(orderInfo);
                var order = db.Orders.Where(e => e.ID == orderID).SingleOrDefault();
                if (hashvalidateResult == "CORRECTED" && txnResponseCode.Trim() == "0")
                {
                    order.Status = OrderStatus.Paid;
                    db.SubmitChanges();
                    return View("Success");
                }
                else if (hashvalidateResult == "INVALIDATED" && txnResponseCode.Trim() == "0")
                {
                    order.Status = OrderStatus.PendingOnline;
                    db.SubmitChanges();
                    return View("Pending");
                }
                else
                {
                    order.Status = OrderStatus.TransactionFail;
                    db.SubmitChanges();
                }
                return View("TransactionFail");
            }
            catch (Exception exp)
            {
                ErrorLog.WriteLog(exp);
                return View("Fail");
            }
        }
        public ActionResult ValidateOnePayWorld()
        {
            try
            {
                string SECURE_SECRET = OnePayPaymentWorld.Hashcode;
                string hashvalidateResult = "";
                // Khoi tao lop thu vien
                VPCRequest conn = new VPCRequest("http://onepay.vn");
                conn.SetSecureSecret(SECURE_SECRET);
                // Xu ly tham so tra ve va kiem tra chuoi du lieu ma hoa
                hashvalidateResult = conn.Process3PartyResponse(Request.QueryString);
                // Lay gia tri tham so tra ve tu cong thanh toan
                String vpc_TxnResponseCode = conn.GetResultField("vpc_TxnResponseCode", "Unknown");
                string amount = conn.GetResultField("vpc_Amount", "Unknown");
                string localed = conn.GetResultField("vpc_Locale", "Unknown");
                string command = conn.GetResultField("vpc_Command", "Unknown");
                string version = conn.GetResultField("vpc_Version", "Unknown");
                string cardType = conn.GetResultField("vpc_Card", "Unknown");
                string orderInfo = conn.GetResultField("vpc_OrderInfo", "Unknown");
                string merchantID = conn.GetResultField("vpc_Merchant", "Unknown");
                string authorizeID = conn.GetResultField("vpc_AuthorizeId", "Unknown");
                string merchTxnRef = conn.GetResultField("vpc_MerchTxnRef", "Unknown");
                string transactionNo = conn.GetResultField("vpc_TransactionNo", "Unknown");
                string acqResponseCode = conn.GetResultField("vpc_AcqResponseCode", "Unknown");
                string txnResponseCode = vpc_TxnResponseCode;
                string message = conn.GetResultField("vpc_Message", "Unknown");

                // Sua lai ham check chuoi ma hoa du lieu
                var orderID = Utils.ParseInt(orderInfo);
                var order = db.Orders.Where(e => e.ID == orderID).SingleOrDefault();
                if (hashvalidateResult == "CORRECTED" && txnResponseCode.Trim() == "0")
                {
                    order.Status = OrderStatus.Paid;
                    db.SubmitChanges();
                    return View("Success");
                }
                else if (hashvalidateResult == "INVALIDATED" && txnResponseCode.Trim() == "0")
                {
                    order.Status = OrderStatus.PendingOnline;
                    db.SubmitChanges();
                    return View("Success");
                }
                else
                {
                    order.Status = OrderStatus.TransactionFail;
                    db.SubmitChanges();
                }
                return View("TransactionFail");
            }
            catch (Exception exp)
            {
                ErrorLog.WriteLog(exp);
                return View("Fail");
            }
        }
        [ChildActionOnly]
        public ActionResult OtherItems(int id, int number, string title, string viewName)
        {
            var a = new ProductListModels();
            var current_product = db.Products.Where(e => e.ID == id).SingleOrDefault();
            var l = ProductManager.GetOtherList(id, 0, current_product.CatID, 0, 0,
                0, 0, 1, 0, 0, 0,1, string.Empty, "ID", "desc", number);
            ViewData["Title"] = title;
            a.ImageUrl = Settings.Default.SiteRootUrl + Settings.Default.ProductRootUrl;
            a.ImagePath = Settings.Default.SiteRootPath + Settings.Default.ProductRootPath;
            a.Products = l;
            return PartialView(viewName, a);
        }        
    }
}
